<template>
  <view w-full box-border pa-20rpx>
    <view w-full bg-white rounded-20rpx box-border px-20rpx pb-30rpx mb-20rpx>
      <view w-full h-90rpx flex items-center style="border-bottom: 1px solid #eeeeee">{{ examTitle }}</view>
      <view h-100rpx flex justify-between items-center>
        <view text-24rpx flex items-end>
          答题进度
          <text ml-16rpx text-36rpx line-height-none>{{ userAnswerNum }}</text>
          /{{ questionNum }}题
        </view>
        <view v-if="type != 9" text-28rpx flex items-center>
          <image w-40rpx h-40rpx mr-10rpx src="/pages/exam/static/time.png"></image>
          <!-- <nut-countdown :endTime="end" format="DD天HH时mm分ss秒" /> -->
          <xm-count-down :expireTime="myExam.answerEndTime" @end="finishAuto" preTxt="" color="#000"></xm-count-down>
        </view>
      </view>
      <view w-360rpx h-20rpx rounded-10rpx bg="#EEEEEE">
        <view bg="#FCC300" h-20rpx rounded-10rpx :style="{ width: (userAnswerNum / questionNum) * 360 + 'rpx' }"></view>
      </view>
    </view>
    <!-- <view w-full :style="{ height: questionHeight + 'px' }" style="border: 1px solid red"></view> -->
    <xm-swiper
      ref="swiperRef"
      v-model="curQuestionIndex"
      :items="examQuestions"
      :height="questionHeight"
      :style="{ height: questionHeight + 'px' }">
      <template #default="{ item: examQuestion }">
        <scroll-view
          v-if="isShowQuestion"
          scroll-y
          enhanced
          :show-scrollbar="false"
          :style="{ height: questionHeight + 'px' }"
          bg-white
          rounded-20rpx
          px-20rpx
          py-30rpx
          box-border>
          <xm-question
            v-if="examQuestion.type === 2"
            v-model="examQuestion.userAnswers"
            :type="examQuestion.questionType"
            :markType="examQuestion.markType"
            :title="examQuestion.title"
            :score="examQuestion.score"
            :answers="examQuestion.answers"
            :userScore="examQuestion.userScore"
            :options="examQuestion.options"
            :analysis="examQuestion.analysis"
            :editable="examing"
            :analysisShow="analysisShow"
            @change="(answers: string[]) => answer(examQuestion, answers)">
            <template #title-pre>
              <text class="mypaper-main__question-cur-no">{{ examQuestion.no }}、</text>
            </template>
            <template #title-post>
              <text>（{{ examQuestion.score }}分）</text>
            </template>
          </xm-question>
          <view v-else>
            <view>{{ examQuestion.chapterName }}</view>
            <view>{{ examQuestion.chapterTxt }}</view>
          </view>
        </scroll-view>
      </template>
    </xm-swiper>
  </view>
  <view bg-white rounded-20rpx ml-20rpx w-710rpx h-120rpx flex justify-between items-center position-fixed bottom-46rpx>
    <image w-40rpx h-40rpx ml-40rpx src="/pages/exam/static/datika.png" @click="answerSheet.open()"></image>
    <view flex justify-end items-center text-28rpx>
      <view
        v-if="curQuestionIndex != 0"
        w-220rpx
        h-80rpx
        bg="#FCC300"
        rounded-40rpx
        flex
        justify-center
        items-center
        mr-28rpx
        @click="pre">
        上一题
      </view>
      <view
        v-if="curQuestionIndex != questionNum - 1"
        w-220rpx
        h-80rpx
        bg="#FCC300"
        rounded-40rpx
        flex
        justify-center
        items-center
        @click="next">
        下一题
      </view>
      <view v-if="type == 9" w-126rpx h-80rpx flex justify-center items-center @click="toBack">返回</view>
      <view v-else w-126rpx h-80rpx flex justify-center items-center @click="finish">交卷</view>
    </view>
  </view>
  <view class="mypaper-foot">
    <xm-popup ref="answerSheet" name="答题卡" class="answer-sheet">
      <view class="answer-sheet-head">
        <!-- <view class="answer-sheet-head__state answer-sheet-head__state--mark"></view>
        <text class="answer-sheet-head__name">标记</text> -->
        <view class="answer-sheet-head__state answer-sheet-head__state--answer"></view>
        <text class="answer-sheet-head__name">已答</text>
      </view>
      <view class="answer-sheet-main">
        <template v-for="(examQuestion, index) in examQuestions" :index="index" :key="index">
          <text v-if="examQuestion.type === 1" @click="curQuestionIndex = index" class="answer-sheet_chapter-name">
            {{ examQuestion.chapterName }}
          </text>
          <view
            v-else
            @click="curQuestionIndex = index"
            :class="[
              'answer-sheet__question-no',
              { 'answer-sheet__question-no--answer': isAnswer(examQuestion) },
              { 'answer-sheet__question-no--mark': isMark(examQuestion) }
            ]">
            <text>{{ examQuestion.no }}</text>
          </view>
        </template>
      </view>
    </xm-popup>
  </view>
</template>

<script setup lang="ts">
import { onLoad, onShow } from '@dcloudio/uni-app'
import { myExamGet, myExamExamGet, myExamPaper, myExamAnswer, myExamFinish } from '@/api/exam'
import xmSwiper from '@/pages/exam/components/xm-swiper/xm-swiper.vue'
import xmQuestion from '@/pages/exam/components/xm-question/xm-question.vue'
import xmCountDown from '@/pages/exam/components/xm-count-down/xm-count-down.vue'
import xmPopup from '@/pages/exam/components/xm-popup/xm-popup.vue'
import type { Question } from '@/ts/question.d.ts'
import type { MyExam } from '@/ts/myExam.d.ts'
import type { Exam } from '@/ts/exam.d.ts'
import type { ExamQuestion } from '@/ts/paper.d.ts'
const end = ref(Date.now() + 60 * 1000)
const examQuestions = ref([{}] as ExamQuestion[])
const answerModel = ref(1) // 答题模式（1：答题；2：背题）
const curQuestionIndex = ref<number>(0) // 当前试题索引
const id = ref<string | number>('')
const type = ref<number>(1) // 1专题;2其他
const swiperRef = ref()
const isShowQuestion = ref(false)
const examTitle = ref<string>('考试')

function pre() {
  swiperRef.value.pre()
  isShowQuestion.value = false
  setTimeout(() => {
    isShowQuestion.value = true
  }, 10)
}
function next() {
  swiperRef.value.next()
  isShowQuestion.value = false
  setTimeout(() => {
    isShowQuestion.value = true
  }, 10)
}

const exam = reactive<Exam>({
  id: null, // 考试信息
  name: '',
  startTime: '',
  endTime: '',
  markStartTime: '',
  markEndTime: '',
  markState: null,
  scoreState: null,
  rankState: null,
  anonState: null,
  passScore: null,
  totalScore: null,
  markType: null,
  genType: null,
  loginType: null,
  sxes: [],
  state: null,
  userNum: null,
  limitMinute: null
})
const myExam = reactive<MyExam>({
  examId: null, // 我的考试信息
  userId: null,
  answerStartTime: '',
  answerEndTime: '',
  markStartTime: '',
  markEndTime: '',
  objectiveScore: null,
  totalScore: null,
  state: null,
  markState: null,
  answerState: null,
  no: null
})

const timerId = ref() // 延时器ID，用于防抖
const answerSheet = ref() // 答题卡
const marks = ref<number[]>([]) // 标记

//试题类型（1：单选；2：多选；3：填空；4：判断；5：问答）
const typeDict = ref<any>({
  1: '单选',
  2: '多选',
  3: '填空',
  4: '判断',
  5: '问答'
})

const examing = computed(() => (myExam.state === 1 && myExam.markState != 3) || myExam.state === 2) // 考试中
// const examing = computed(() => true) // 考试中
const analysisShow = computed(() => {
  return (
    (exam.scoreState == 1 && exam.markState == 3) || // 如果是考试结束后显示成绩，需要等到考试结束
    (exam.scoreState == 3 && myExam.markState == 3) // 如果是交卷后显示成绩，需要等到该试卷阅卷完成。比如主观题没阅卷，得不到总分，得不到是否及格
  )
}) // 结果显示
const questionNum = computed(() => {
  return examQuestions.value.reduce((total, examQuestion) => {
    return examQuestion.type === 2 ? total + 1 : total
  }, 0)
}) // 试题数量
const userAnswerNum = computed(() => {
  return examQuestions.value.reduce((total, examQuestion) => {
    return examQuestion.type === 2 && examQuestion.userAnswers?.some((userAnswer) => userAnswer.length > 0)
      ? total + 1
      : total
  }, 0)
}) // 用户答题数量
const isAnswer = computed(
  () => (examQuestion: ExamQuestion) => examQuestion.userAnswers?.some((userAnswer) => userAnswer.length)
) // 是否作答
const isMark = computed(() => (examQuestion: ExamQuestion) => marks.value.includes(examQuestion.no)) // 是否标记

// 试题滚动高度
const questionHeight = computed(() => {
  const systemInfo: any = uni.getSystemInfoSync()
  return systemInfo.windowHeight - (systemInfo.screenWidth / 750) * 488
})

async function examQuery() {
  let response = await myExamExamGet({ examId: exam.id })
  const data = response.data.result
  exam.name = data.name
  exam.startTime = data.startTime
  exam.endTime = data.endTime
  exam.markStartTime = data.markStartTime
  exam.markEndTime = data.markEndTime
  exam.markState = data.markState
  exam.scoreState = data.scoreState
  exam.rankState = data.rankState
  exam.anonState = data.anonState
  exam.passScore = data.passScore
  exam.totalScore = data.totalScore
  exam.markType = data.markType
  exam.genType = data.genType
  exam.sxes = data.sxes
  exam.state = data.state
  exam.userNum = data.userNum
  exam.limitMinute = data.limitMinute
}
// 我的考试查询
async function myExamQuery() {
  let response = await myExamGet({ examId: exam.id })
  const data = response.data.result
  myExam.examId = data.examId
  myExam.userId = data.userId
  myExam.answerStartTime = data.answerStartTime
  myExam.answerEndTime = data.answerEndTime
  myExam.markStartTime = data.markStartTime
  myExam.markEndTime = data.markEndTime
  myExam.objectiveScore = data.objectiveScore
  myExam.totalScore = data.totalScore
  myExam.state = data.state
  myExam.markState = data.markState
  myExam.answerState = data.answerState
  myExam.no = data.no
}

// 试卷查询
async function paperQuery() {
  let { data } = await myExamPaper({ examId: exam.id })
  let no = 1
  examQuestions.value = (data.result as any[]).map((examQuestion: ExamQuestion) => {
    if (examQuestion.type === 2) {
      examQuestion.no = no++ // 处理题号
    }
    return examQuestion
  })
}

// 作答
function answer(examQuestion: ExamQuestion, answers: string[]) {
  clearTimeout(timerId.value)
  timerId.value = setTimeout(async () => {
    await myExamAnswer({
      examId: exam.id,
      questionId: examQuestion.questionId,
      answers: answers
    })
  }, 500)
}

// 标记
function mark(no: number) {
  if (marks.value.includes(no)) {
    marks.value = marks.value.filter((_no) => _no != no)
  } else {
    marks.value.push(no)
  }
}

// 进度
// function percent(curTime: Date) {
// 	let answerStartTime = new Date(myExam.answerStartTime.replaceAll('-', '/'));
// 	let answerEndTime = new Date(myExam.answerEndTime.replaceAll('-', '/'));
// 	let total = answerEndTime.getTime() - answerStartTime.getTime();
// 	let remind = answerEndTime.getTime() - curTime.getTime();
// 	timePercent.value = Math.floor(((total - remind) / total) * 100);
// }

// 交卷
async function finish() {
  let unAnswerNum = questionNum.value - userAnswerNum.value
  uni.showModal({
    title: '提示消息',
    content: unAnswerNum ? `剩余${unAnswerNum}道题未答，是否交卷？` : `共${questionNum.value}道题全部已答，是否交卷？`,
    showCancel: true,
    success: async (res) => {
      if (res.cancel) {
        return
      }

      await finishAuto()
    }
  })
}

// 自动交卷
async function finishAuto() {
  if (!examing.value) {
    return
  }

  // 交卷
  uni.showLoading({ title: '交卷中', mask: true })
  await myExamFinish({ examId: exam.id })

  // 如果考试成绩是不公布，返回首页
  if (exam.scoreState === 2) {
    uni.hideLoading()
    prompt('考试已结束')
    return
  }

  // 如果考试成绩是交卷后公布，并且是主观题试卷，提示后返回首页（需人工阅卷）
  // if (exam.scoreState === 3 && exam.markType === 2) {
  // 	uni.hideLoading();// 情况不存在，业务上做了主观题试卷不允许交卷后公布，允许也没有意义
  // 	prompt(`主观题未阅，请于${exam.markEndTime}后查询`);
  // 	return;
  // }

  // 如果考试成绩是交卷后公布，并且是客观题试卷，查询成绩
  if (exam.scoreState === 3 && exam.markType === 1) {
    uni.hideLoading()
    await scoresView()
    return
  }

  // 如果考试成绩是考试结束后公布，但是提前交卷，提示后返回首页
  // let { data } = await loginSysTime();
  let curTime = new Date()
  let examEndTime = new Date(exam.endTime.replaceAll('-', '/'))
  let remainSecond = (examEndTime.getTime() - curTime.getTime()) / 1000
  if (exam.scoreState === 1 && remainSecond > 3) {
    uni.hideLoading()
    prompt(`整场考试未结束，请于${exam.endTime}后查询`)
    return
  }

  // 如果考试成绩是考试结束后公布，并且在接近整场考试结束时交卷，查询成绩
  if (exam.scoreState === 1 && remainSecond <= 3) {
    uni.hideLoading()
    await scoresView() // 主观题试卷可以先看客观题得分
    return
  }
  uni.navigateBack()
}

// const formatDate = (date: Date): string => {
//   const padZero = (num: number): string => (num < 10 ? `0${num}` : num.toString())

//   const year = date.getFullYear()
//   const month = padZero(date.getMonth() + 1)
//   const day = padZero(date.getDate())
//   const hours = padZero(date.getHours())
//   const minutes = padZero(date.getMinutes())
//   const seconds = padZero(date.getSeconds())

//   return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`
// }

// 成绩预览
async function scoresView(queryCount: number = 6) {
  uni.showLoading({ title: '成绩查询中', mask: true })
  for (let i = 0; i < queryCount; i++) {
    if (i >= 5) {
      prompt(`查询失败，请稍后再次查询`)
      return
    }

    await new Promise((res) => setTimeout(res, 1000))
    await myExamQuery()

    if (myExam.markState == 2) {
      uni.hideLoading() // 主观题需人工阅卷，先展示客观题得分
      prompt(`客观题${myExam.objectiveScore}分，总分请于${exam.markEndTime}后查询`)
      return
    }
    if (myExam.markState == 3) {
      uni.hideLoading()
      prompt(
        `客观题${myExam.objectiveScore}分，总${myExam.totalScore}分, 成绩${myExam.answerState == 1 ? '及格' : '不及格'}`
      )
      return
    }
  }
}

// 提示
function prompt(msg: string) {
  uni.showModal({
    title: '提示消息',
    content: msg,
    confirmText: '查看详情',
    cancelText: '返回首页',
    success: function (res) {
      if (res.confirm) {
        uni.redirectTo({ url: `/pages/exam/examList?type=9` })
      } else if (res.cancel) {
        toHome()
      }
    }
  })
}

// 去首页
function toHome() {
  uni.switchTab({ url: '/pages/index' })
}

function toBack() {
  uni.navigateBack()
}

onMounted(() => {})
// onLoad((options: any) => {
//   id.value = options.id
//   if (options.type) {
//     type.value = parseInt(options.type)
//   }

//   questionQuery()
//   addExmQuestionTypeCount()
// })
onLoad(async (options: any) => {
  exam.id = options.examId
  if (options.type) {
    type.value = options.type
  }
  try {
    await paperQuery() //先打开试卷，生成考试时间，改为考试中，在查询我的考试信息

    await myExamQuery() // 放在paperQuery后面执行

    await examQuery()
    isShowQuestion.value = true
    uni.setNavigationBarTitle({
      title: exam.name
    })
    examTitle.value = exam.name
  } catch (error) {
    setTimeout(() => {
      uni.navigateBack()
    }, 2000)
  }
})
</script>
<style>
page {
}
</style>
<style scoped lang="scss">
// #ifdef MP-WEIXIN
:deep(swiper) {
  height: 100%;
  swiper-item {
    & > view {
      height: 100%;
    }
  }
}
// #endif
.mypaper-foot {
  display: flex;
  margin: 20rpx 30rpx;
  .answer-nav {
    flex: 1;
    display: flex;
    align-items: center;
    .answer-nav__icon {
      background-clip: text;
      color: transparent;
      background-image: linear-gradient(0deg, #259ff8, #04c7f2);
    }
    .answer-nav__outer {
      display: flex;
      flex-direction: column;
      margin-left: 10rpx;
      .answer-nav__inner {
        display: flex;
        justify-content: center;
        line-height: 20rpx;
        .answer-nav__cur {
          font-size: 24rpx;
          color: #0d9df6;
        }
        .answer-nav__total {
          font-size: 24rpx;
          color: #303133;
        }
      }
      .answer-nav__text {
        font-size: 24rpx;
        color: #8f939c;
      }
    }
  }
  .mypaper-foot__pre-question {
    width: 160rpx;
    height: 66rpx;
    line-height: 66rpx;
    font-size: 30rpx;
    color: #0d9df6;
    border-radius: 33rpx;
    margin: 0rpx 0rpx 0rpx 20rpx;
    background-color: white;
    border: 1rpx solid #04c7f2;
    &::after {
      border: 0rpx;
    }
  }
  .mypaper-foot__next-question {
    width: 160rpx;
    height: 66rpx;
    line-height: 66rpx;
    font-size: 30rpx;
    color: #0d9df6;
    border-radius: 33rpx;
    margin: 0rpx 0rpx 0rpx 20rpx;
    background-color: white;
    border: 1rpx solid #04c7f2;
    &::after {
      border: 0rpx;
    }
  }
  .mypaper-foot__finish {
    width: 160rpx;
    height: 66rpx;
    line-height: 66rpx;
    font-size: 32rpx;
    color: #ffffff;
    border-radius: 33rpx;
    background: linear-gradient(to right, #04c7f2 0%, #259ff8 100%);
    margin: 0rpx 0rpx 0rpx 20rpx;
    &::after {
      border: 0rpx;
    }
  }
  .answer-sheet {
    .answer-sheet-head {
      display: flex;
      justify-content: end;
      align-items: center;
      margin-bottom: 30rpx;
      .answer-sheet-head__state {
        width: 22rpx;
        height: 22rpx;
        margin-left: 30rpx;
        border-radius: 50%;
        background: #000;
        border: 1rpx solid #000;
      }
      .answer-sheet-head__state--default {
        background: #e9e9eb;
        border: 1rpx solid #8f939c;
      }
      .answer-sheet-head__state--answer {
        background: #d4e4ff;
        border: 1rpx solid #2979ff;
      }
      .answer-sheet-head__state--mark {
        background: #fdedd9;
        border: 1rpx solid #f3a73f;
      }
      .answer-sheet-head__name {
        margin-left: 10rpx;
        font-size: 30rpx;
        color: #8f939c;
      }
    }
    .answer-sheet-main {
      flex: 1;
      display: grid;
      grid-template-columns: repeat(9, 1fr);
      gap: 5px 5px;
      .answer-sheet_chapter-name {
        grid-column: 1 / -1;
        margin-top: 10px;
        font-size: 36rpx;
        color: #303133;
      }
      .answer-sheet__question-no {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 60rpx;
        height: 60rpx;
        border-radius: 50%;
        font-size: 32rpx;
        color: #8f939c;
        border: 1px solid #8f939c;
        background-color: #e9e9eb;
      }
      .answer-sheet__question-no--answer {
        color: #2979ff;
        border: 1px solid #2979ff;
        background-color: #d4e4ff;
      }
      .answer-sheet__question-no--mark {
        color: #f3a73f;
        border: 1px solid #f3a73f;
        background-color: #fdedd9;
      }
    }
  }
}
</style>
